package com.cug.nageoffer.websocket;

import com.alibaba.fastjson.JSON;
import com.cug.nageoffer.model.entity.Peer;
import com.cug.nageoffer.service.PeerService;
import com.cug.nageoffer.util.AuthContextUtil;
import jakarta.annotation.Resource;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint(value = "/chat/meet/{peerId}")
public class WebSocketPeerServer {

    @Resource
    private PeerService peerService;

    private static final Map<String, Session> peerIdSessionMap = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("peerId") String peerId) {
        log.info("用户连接视频服务器成功，session :{},peer id is:{}", session.getId(), peerId);
        Peer p = peerService.query().eq("user_id", AuthContextUtil.get().getId()).one();
        Peer peer = Peer.builder().userId(AuthContextUtil.get().getId()).peerId(peerId).build();
        if(p==null){
            peerService.save(peer);
        }
        else{
            peerService.update().eq("user_id",peer.getUserId()).set("peer_id",peer.getPeerId()).update();
        }
        Session removedSession = WebSocketPeerServer.peerIdSessionMap.remove(peerId);
        try {
            if (Objects.nonNull(removedSession)) {
                removedSession.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            WebSocketPeerServer.peerIdSessionMap.put(peerId, session);
            refreshOnlineSessionsList();
        }
    }

    @OnClose
    public void onClose(Session session, @PathParam("peerId") String peerId) {
        log.warn("on close:the session is is :{},the peer id is:{}", session.getId(), peerId);

        Session removedSession = WebSocketPeerServer.peerIdSessionMap.remove(peerId);
        try {
            if (Objects.nonNull(removedSession)) {
                removedSession.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            refreshOnlineSessionsList();
        }
    }

//    @OnMessage
//    public void onMessage(Session session, String stringMessage) {
//        log.info("onMessage:the session is:{},the stringMessage is:{}", session, stringMessage);
//    }


    @OnError
    public void onError(Session session, Throwable e, @PathParam("peerId") String peerId) {
        log.error("on error:the session is is :{},the exception class is: {},the peer id is:{}", session.getId(), e.getClass(), peerId);
        onClose(session, peerId);
        log.error("meet发生了错误：{}", Arrays.toString(e.getStackTrace()));
    }

    private void refreshOnlineSessionsList() {
        WebSocketPeerServer.peerIdSessionMap.forEach((key, value) ->
                value.getAsyncRemote().sendText(JSON.toJSONString(WebSocketPeerServer.peerIdSessionMap.keySet())));
    }

}
